using System;
using System.Collections.Generic;
using System.Threading;
using System.Diagnostics;
using SwModem.Com;
using Dff;


namespace SwModem.Fsk
{
    /// <summary>
    /// Graph Node: A ITU-T V.21 modem. FSK 300bps, two tones, very low bandwidth
    /// </summary>
    //public class V21 : Node
    //{
    //    private Port<byte>   _pOData;
    //    private Port<byte>   _pIData;
    //    private Port<double> _pOWave;
    //    private Port<double> _pIWave;

    //    private FskTx        _fskTx;
    //    private FskRx        _fskRx;
    //    private FskSetupInfo _fskSetupInfo;
        

    //    #region Constructors
    //    public V21()
    //    {
    //        _name    = "Modem V.21";
    //        _desc    = "Software-Defined Modem, rec ITU V.21";
    //        _status  = NodeStatus.Stopped;
    //        _sched   = new WorkerQueue(_name);
            
    //        _threads    = new Thread[1];
    //        _threads[0] = _sched.Thread;

    //        TaskDelegate event1 = new TaskDelegate(Event_DataSnk);
    //        TaskDelegate event2 = new TaskDelegate(Event_DataSrc);
    //        TaskDelegate event3 = new TaskDelegate(Event_WaveSnk);
    //        TaskDelegate event4 = new TaskDelegate(Event_WaveSrc);

    //        int dataGrain = 1;
    //        int waveGrain = 8 * _fskSetupInfo.FskSymbolSize;

    //        _pIData = new Port<byte>  ("IDATA", IOType.I, dataGrain, _sched, event1);
    //        _pOData = new Port<byte>  ("ODATA", IOType.O, dataGrain, _sched, event2);
    //        _pIWave = new Port<double>("IWAVE", IOType.I, waveGrain, _sched, event3);
    //        _pOWave = new Port<double>("OWAVE", IOType.O, waveGrain, _sched, event4);
            
    //        _fskSetupInfo = new FskSetupInfo();
    //        _fskTx        = new FskTx(_fskSetupInfo);
    //        _fskRx        = new FskRx(_fskSetupInfo);
    //    }
    //    #endregion

    //    #region Interface of INode

    //    public override int Control(NodeExeCtl cmd)
    //    {
    //        switch (cmd)
    //        {
    //            case NodeExeCtl.Start:
    //                _status = NodeStatus.Running;
    //                _sched.Start();
    //                break;

    //            case NodeExeCtl.Stop:
    //                _status = NodeStatus.Stopped;
    //                _sched.Stop();
    //                break;

    //            case NodeExeCtl.Pause:
    //                _status = NodeStatus.Paused;
    //                _sched.Stop();
    //                break;
    //            case NodeExeCtl.Abort:
    //                if (_status != NodeStatus.Stopped)
    //                    throw new Exception("Non-stopped. Stop the node first.");
    //                else
    //                    _sched.Abort();
    //                break;
    //        }

    //        return 0;
    //    }

        
    //    #endregion

    //    #region Event Handlers

    //    /// <summary>
    //    /// Changes has ocurred in TX queues: data available on input data buffer or free space 
    //    /// available in output wave buffer. MODULATOR
    //    /// </summary>
    //    private void Event_DataSnk() 
    //    {
    //        TxBBFC();
    //    }

    //    private void Event_WaveSrc()
    //    {
    //        TxBBFC();
    //    }


    //    /// <summary>
    //    /// Changes has ocurred in RX queues: wave samples available on input wave buffer or free 
    //    /// space on output data buffer. DEMODULATOR
    //    /// </summary>
    //    private void Event_DataSrc() 
    //    {
            
    //    }

    //    private void Event_WaveSnk() 
    //    { 
    //    }


    //    // CBBFC Check Bound-Buffer Fireable Condition And Fire If Needed
    //    private void TxBBFC() 
    //    {
    //        // Bound-Buffer Fireable Condition
    //        if ((_pIData.TokenCount < _pIData.Grain) || (_pOWave.BufferFree < _pOWave.Grain))
    //            return; 

    //        int actual;
    //        actual = _pIData.XferData(_fskTx.PortI.Buffer, 0, _fskTx.PortI.TokenCount);
    //        if (actual != _fskTx.PortI.TokenCount)
    //            throw new Exception("Jai!");

    //        _fskTx.Go();

    //        actual = _pOWave.XferData(_fskTx.PortO.Buffer, 0, _fskTx.PortO.TokenCount);
    //        if (actual != _fskTx.PortO.TokenCount)
    //            throw new Exception("Jai!");

    //    }

    //    #endregion

    //    #region Ports
    //    public Port<byte>   PortIDATA { get { return _pIData; } }
    //    public Port<byte>   PortODATA { get { return _pOData; } }
    //    public Port<double> PortIWAVE { get { return _pIWave; } }
    //    public Port<double> PortOWAVE { get { return _pOWave; } }
    //    #endregion

    //}
}
